﻿using PARK.Common.Enum;
using PARK.Common.Extension;
using PARK.Common.Util;
using PARK.Dependency;
using PARK.DynamicApiController;
using PARK.Expand.Thirdparty;
using PARK.Expand.Thirdparty.DingDing;
using PARK.FriendlyException;
using PARK.LinqBuilder;
using PARK.System.Entitys.Dto.Permission.Organize;
using PARK.System.Entitys.Dto.System.SynThirdInfo;
using PARK.System.Entitys.Dto.System.SysConfig;
using PARK.System.Entitys.Permission;
using PARK.System.Entitys.System;
using PARK.System.Interfaces.System;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Yitter.IdGenerator;

namespace PARK.System.Core.Service.SynThirdInfo
{
    /// <summary>
    /// 第三方同步
    /// 版 本：V3.2


    /// 日 期：2021-06-01 
    /// </summary>
    [ApiDescriptionSettings(Tag = "System", Name = "SynThirdInfo", Order = 210)]
    [Route("api/system/[controller]")]
    public class SynThirdInfoService: ISynThirdInfoService, IDynamicApiController, ITransient
    {
        private readonly ISqlSugarRepository<SynThirdInfoEntity> _synThirdInfoRepository;
        private readonly ISysConfigService _sysConfigService;
        private readonly ISqlSugarRepository<OrganizeEntity> _organizeRepository;
        private readonly ISqlSugarRepository<UserEntity> _userRepository;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="synThirdInfoRepository"></param>
        /// <param name="sysConfigService"></param>
        /// <param name="organizeRepository"></param>
        /// <param name="userRepository"></param>
        public SynThirdInfoService(ISqlSugarRepository<SynThirdInfoEntity> synThirdInfoRepository, ISysConfigService sysConfigService, ISqlSugarRepository<OrganizeEntity> organizeRepository, ISqlSugarRepository<UserEntity> userRepository)
        {
            _synThirdInfoRepository = synThirdInfoRepository;
            _sysConfigService = sysConfigService;
            _organizeRepository = organizeRepository;
            _userRepository = userRepository;
        }

        #region Get
        /// <summary>
        /// 列表
        /// </summary>
        /// <param name="thirdType">请求参数</param>
        /// <returns></returns>
        [HttpGet("getSynThirdTotal/{thirdType}")]
        public async Task<dynamic> GetList(int thirdType)
        {
            var whereLambda = LinqExpression.And<SynThirdInfoEntity>();
            whereLambda = whereLambda.And(x => x.ThirdType == thirdType);
            return await GetListByThirdType(whereLambda,"用户", "组织");
        }

        /// <summary>
        /// 钉钉同步组织
        /// </summary>
        /// <returns></returns>
        [HttpGet("synAllOrganizeSysToDing")]
        public async Task<dynamic> synAllOrganizeSysToDing()
        {
            var whereLambda = LinqExpression.And<SynThirdInfoEntity>();
            whereLambda = whereLambda.And(x => x.ThirdType == 2 && x.DataType < 3);
            return await GetListByThirdType(whereLambda, "组织", "组织");
        }

        /// <summary>
        /// 企业微信同步组织
        /// </summary>
        /// <returns></returns>
        [HttpGet("synAllOrganizeSysToQy")]
        public async Task<dynamic> synAllOrganizeSysToQy()
        {
            var whereLambda = LinqExpression.And<SynThirdInfoEntity>();
            whereLambda = whereLambda.And(x => x.ThirdType == 1 && x.DataType < 3);
            return await GetListByThirdType(whereLambda, "组织", "组织");
        }

        /// <summary>
        /// 钉钉同步用户
        /// </summary>
        /// <returns></returns>
        [HttpGet("synAllUserSysToDing")]
        public async Task<dynamic> synAllUserSysToDing()
        {
            var whereLambda = LinqExpression.And<SynThirdInfoEntity>();
            whereLambda = whereLambda.And(x => x.ThirdType == 2 && x.DataType == 3);
            return await GetListByThirdType(whereLambda, "用户", "用户");
        }

        /// <summary>
        /// 企业微信同步用户
        /// </summary>
        /// <returns></returns>
        [HttpGet("synAllUserSysToQy")]
        public async Task<dynamic> synAllUserSysToQy()
        {
            var whereLambda = LinqExpression.And<SynThirdInfoEntity>();
            whereLambda = whereLambda.And(x => x.ThirdType == 1 && x.DataType == 3);
            return await GetListByThirdType(whereLambda, "用户", "用户");
        }
        #endregion

        #region Method
        /// <summary>
        /// 获取同步数据
        /// </summary>
        /// <param name="whereLambda"></param>
        /// <param name="synType1"></param>
        /// <param name="synType2"></param>
        /// <returns></returns>
        private async Task<dynamic> GetListByThirdType(Expression<Func<SynThirdInfoEntity, bool>> whereLambda,string synType1,string synType2)
        {
            var synThirdInfoList = await _synThirdInfoRepository.Entities.Where(whereLambda).ToListAsync();
            var userList = await _userRepository.Entities.Where(x => x.DeleteMark == null).ToListAsync();
            var orgList = await _organizeRepository.Entities.Where(x => x.DeleteMark == null).ToListAsync();
            if (synType1.Equals(synType2))
            {
                var output = new SynThirdInfoConutOutput()
                {
                    synType = synType1,
                    recordTotal = synType1.Equals("组织") ? orgList.Count : userList.Count,
                    synDate= synThirdInfoList.Select(x => x.LastModifyTime).ToList().Max().IsEmpty() ? synThirdInfoList.Select(x => x.CreatorTime).ToList().Max() : synThirdInfoList.Select(x => x.LastModifyTime).ToList().Max(),
                    synFailCount = synThirdInfoList.FindAll(x => x.SynState.Equals("2")).Count,
                    synSuccessCount = synThirdInfoList.FindAll(x => x.SynState.Equals("1")).Count,
                    unSynCount = synThirdInfoList.FindAll(x => x.SynState.Equals("0")).Count,
                };
                return output;


            }
            else
            {
                var output = new List<SynThirdInfoConutOutput>();
                var synUserList = synThirdInfoList.FindAll(x => x.DataType == 3);
                var synOrgList = synThirdInfoList.FindAll(x => x.DataType < 3);
                output.Add(new SynThirdInfoConutOutput()
                {
                    synType = synType2,
                    recordTotal = synType2.Equals("组织") ? orgList.Count : userList.Count,
                    synDate = synOrgList.Select(x => x.LastModifyTime).ToList().Max().IsEmpty() ? synOrgList.Select(x => x.CreatorTime).ToList().Max() : synOrgList.Select(x => x.LastModifyTime).ToList().Max(),
                    synFailCount = synOrgList.FindAll(x => x.SynState.Equals("2")).Count,
                    synSuccessCount = synOrgList.FindAll(x => x.SynState.Equals("1")).Count,
                    unSynCount = synOrgList.FindAll(x => x.SynState.Equals("0")).Count,
                });
                output.Add(new SynThirdInfoConutOutput() {
                    synType = synType1,
                    recordTotal = synType1.Equals("组织") ? orgList.Count : userList.Count,
                    synDate = synUserList.Select(x => x.LastModifyTime).ToList().Max().IsEmpty() ? synUserList.Select(x => x.CreatorTime).ToList().Max() : synUserList.Select(x => x.LastModifyTime).ToList().Max(),
                    synFailCount = synUserList.FindAll(x => x.SynState.Equals("2")).Count,
                    synSuccessCount = synUserList.FindAll(x => x.SynState.Equals("1")).Count,
                    unSynCount = synUserList.FindAll(x => x.SynState.Equals("0")).Count,
                });
                return output;
            }
        }      


        /// <summary>
        /// 判断是否存在同步数据
        /// </summary>
        /// <param name="id"></param>
        /// <param name="thirdType"></param>
        /// <param name="dataType"></param>
        /// <returns></returns>
        private bool IsExistThirdObjId(string id, int thirdType, int dataType)
        {
            var falg = _synThirdInfoRepository.Any(x => x.ThirdType == thirdType && x.DataType == dataType && x.SysObjId.Equals(id)&&!SqlFunc.IsNullOrEmpty(x.ThirdObjId));
            return !falg;
        }

        /// <summary>
        /// 保存同步数据
        /// </summary>
        /// <param name="thirdType"></param>
        /// <param name="dataType"></param>
        /// <param name="sysObjId"></param>
        /// <param name="thirdObjId"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private async Task Save(int thirdType, int dataType, string sysObjId, string thirdObjId, string msg)
        {
            var entity = await _synThirdInfoRepository.FirstOrDefaultAsync(x => x.SysObjId == sysObjId && x.ThirdType == thirdType);
            if (entity==null)
            {
                entity = new SynThirdInfoEntity();
                entity.Id = YitIdHelper.NextId().ToString();
                entity.ThirdType = thirdType;
                entity.DataType = dataType;
                entity.SysObjId = sysObjId;
                entity.ThirdObjId = thirdObjId;
                entity.SynState = thirdObjId.IsNullOrEmpty() ? "2" : "1";
                entity.Description = msg;
                var newDic = await _synThirdInfoRepository.Context.Insertable(entity).CallEntityMethod(m => m.Creator()).ExecuteReturnEntityAsync();
                _ = newDic ?? throw PARKException.Oh(ErrorCode.D9005);
            }
            else
            {
                entity.ThirdObjId = thirdObjId;
                entity.SynState = thirdObjId.IsEmpty() ? "2" : "1";
                entity.Description = msg;
                var isOk = await _synThirdInfoRepository.Context.Updateable(entity).IgnoreColumns(ignoreAllNullColumns: true).CallEntityMethod(m => m.LastModify()).ExecuteCommandAsync();
                if (isOk < 0)
                    throw PARKException.Oh(ErrorCode.D9006);
            }
        }

        /// <summary>
        /// 获取第三方部门
        /// </summary>
        /// <param name="organizeId"></param>
        /// <param name="thirdType"></param>
        /// <param name="thirdDepList"></param>
        private void GetThirdDep(string organizeId, int thirdType, List<int> thirdDepList)
        {
            var info = _synThirdInfoRepository.FirstOrDefault(x => x.SysObjId == organizeId && x.ThirdType == thirdType);
            if (info.IsNotEmptyOrNull() && info.ThirdObjId.IsNotEmptyOrNull())
            {
                thirdDepList.Add(Convert.ToInt32(info.ThirdObjId));
            }
        }

        /// <summary>
        /// 根据系统主键获取第三方主键
        /// </summary>
        /// <param name="ids">系统主键</param>
        /// <param name="thirdType">第三方类型</param>
        /// <param name="dataType">数据类型</param>
        /// <returns></returns>
        [NonAction]
        public async Task<List<string>> GetThirdIdList(List<string> ids,int thirdType,int dataType)
        {
            return await _synThirdInfoRepository.Entities.Where(x => x.ThirdType == thirdType
            && x.DataType == dataType && !SqlFunc.IsNullOrEmpty(x.ThirdObjId)).
            In(x => x.SysObjId, ids.ToArray()).Select(x=>x.ThirdObjId).ToListAsync();
        }

        #endregion
    }
}
